import RVOMath from "./rvo/RVOMath";
import Simulator from "./rvo/Simulator";
import Vector2D from "./rvo/Vector2D";

export default class GameMgr {
	private simulator: Simulator;
	private spList: Laya.Sprite[] = [];
	private spR: number = 5;

	constructor() {
		console.log("================================================");
		console.log("RVO_test");
		console.log("================================================");

		this.simulator = new Simulator();
		let simulator = this.simulator;
		simulator.setAgentDefaults(
			this.spR * 4,
			10,
			500,
			50,
			this.spR * 2.2,
			this.spR,
			new Vector2D(0, 0)
		);

		let counts = 10;
		for (let i = 0; i < counts; i++) {
			// const angle = i * (2 * Math.PI) / counts;
			// let x = Math.cos(angle) * 200;
			// let y = Math.sin(angle) * 200;

			let x = 30 * Math.round(i / 5) - 50;
			if (i < counts >> 1) {
				x -= 100;
			} else {
				x += 100;
			}
			let y = 30 * (i % 10) - 50;
			// if (i < 50) y -= 200;

			simulator.addAgent(null);
			console.log(i, x, y);
			simulator.setAgentPosition(i, new Vector2D(x, y));
			let sp = new Laya.Sprite();
			sp.graphics.drawCircle(0, 0, this.spR * 2, "blue");
			sp.graphics.fillText(i + "", 0, 0, "20px Arial", "#ff0000", "center");
			Laya.stage.addChild(sp);
			this.spList.push(sp);
		}

		for (let i = 0; i < simulator.getNumAgents(); i++) {
			let goal = simulator.getAgentPosition(i).clone(); //.scale(-1);
			if (i < counts >> 1) {
				goal.x += 300;
			} else {
				goal.x -= 300;
			}
			// let goal = new Vector2D(Laya.stage.width() / 2, Laya.stage.height / 2);
			simulator.setAgentGoal(i, goal);
		}

		let obstacle1: Vector2D[] = [];
		obstacle1.push(new Vector2D(-10.0, 40.0));
		obstacle1.push(new Vector2D(-80.0, 40.0));
		obstacle1.push(new Vector2D(-80.0, 10.0));
		obstacle1.push(new Vector2D(-10.0, 10.0));
		simulator.addObstacle(obstacle1);

		let sp1 = new Laya.Sprite();
		sp1.graphics.drawPoly(
			300,
			300,
			[-10.0, 40.0, -80.0, 40.0, -80.0, 10.0, -10.0, 10.0],
			"#FF7F50"
		);
		Laya.stage.addChild(sp1);

		let obstacle2: Vector2D[] = [];
		obstacle2.push(new Vector2D(50.0, 60.0));
		obstacle2.push(new Vector2D(30.0, 30.0));
		obstacle2.push(new Vector2D(50.0, -10.0));
		obstacle2.push(new Vector2D(80.0, 20.0));
		obstacle2.push(new Vector2D(70.0, 60.0));
		simulator.addObstacle(obstacle2);

		let sp2 = new Laya.Sprite();
		sp2.graphics.drawPoly(
			0,
			0,
			[50.0, 60.0, 30.0, 30.0, 50.0, -10.0, 80.0, 20.0, 70.0, 60.0],
			"#FF7F50"
		);
		Laya.stage.addChild(sp2);

		let sp3 = new Laya.Sprite();
		sp3.graphics.drawCircle(
			Laya.stage.width / 2,
			Laya.stage.height / 2,
			this.spR * 5,
			null,
			"red"
		);
		Laya.stage.addChild(sp3);

		simulator.processObstacles();
		Laya.timer.frameLoop(1, this, this.step);
		Laya.stage.on(Laya.Event.MOUSE_DOWN, this, this.mouseDown);
		Laya.stage.on(Laya.Event.MOUSE_MOVE, this, this.mouseMove);

		// RovDebug.ins.start(Laya.stage, simulator);
	}

	/** 侦听鼠标按下时 */
	mouseDown(e: Event): void {
		//记录按下的touchId，用于判断是否是按下的事件
		let x = Laya.stage.mouseX;
		let y = Laya.stage.mouseY;
		for (let i = 0; i < this.simulator.getNumAgents(); i++) {
			this.simulator.setAgentGoal(
				i,
				new Vector2D(
					x + (Math.random() * 2 - 1) * this.spR * 4,
					y + (Math.random() * 2 - 1) * this.spR * 4
				)
			);
		}
	}

	/** 侦听鼠标按下时 */
	mouseMove(e: Event): void {
		//记录按下的touchId，用于判断是否是按下的事件
		let x = Laya.stage.mouseX;
		let y = Laya.stage.mouseY;
		console.log("m:", x, y);
		for (let i = 0; i < this.simulator.getNumAgents(); i++) {
			this.simulator.setAgentGoal(
				i,
				new Vector2D(
					x + (Math.random() * 2 - 1) * this.spR * 2,
					y + (Math.random() * 2 - 1) * this.spR * 2
				)
			);
		}
	}

	step() {
		let simulator = this.simulator;

		for (let i = 0; i < simulator.getNumAgents(); ++i) {
			let agentPos = simulator.getAgentPosition(i);
			let sp = this.spList[i];
			if (
				RVOMath.absSq(simulator.getGoal(i).minus(agentPos)) <
				this.spR * this.spR * 36 //RVOMath.RVO_EPSILON
			) {
				// Agent is within one radius of its goal, set preferred velocity to zero
				simulator.setAgentPrefVelocity(i, new Vector2D(0.0, 0.0));
				console.log(
					"finish " +
						i +
						" , disSqr:" +
						RVOMath.absSq(simulator.getGoal(i).minus(agentPos))
				);
				sp.graphics.clear();
				sp.graphics.drawCircle(0, 0, this.spR * 2, "green");
				// console.log(i, agent, simulator.getGoal(i));
			} else {
				sp.graphics.clear();
				sp.graphics.drawCircle(0, 0, this.spR * 2, "blue");
				sp.graphics.fillText(i + "", 0, 0, "20px Arial", "#ff0000", "center");

				// let v = RVOMath.normalize(simulator.getGoal(i).minus(agent)).scale(2);
				let goalVector = simulator.getGoal(i).minus(agentPos);
				// Agent is far away from its goal, set preferred velocity as unit vector towards agent's goal.
				if (RVOMath.absSq(goalVector) > 1.0) {
					goalVector = RVOMath.normalize(goalVector).scale(this.spR);
				}
				simulator.setAgentPrefVelocity(i, goalVector);

				// let angle = Math.random() * 2.0 * Math.PI;
				// let dist = Math.random() * 0.0001;

				// let deta = new Vector2D(Math.cos(angle) * dist, Math.sin(angle) * dist);
				// simulator.setAgentPrefVelocity(
				// 	i,
				// 	goalVector.x + deta.x,
				// 	goalVector.y + deta.y
				// );
			}
			this.spList[i].x = agentPos.x;
			this.spList[i].y = agentPos.y;
			// console.log(i, simulator.getAgentPosition(0), simulator.getGoal(0));
		}
		let dt = Laya.timer.delta;
		dt = Math.min(dt, 33);
		simulator.run(dt);

		// console.log(simulator)
		// if (simulator.reachedGoal()) {
		// 	Laya.timer.clear(this, this.step);
		// 	console.log("finish");
		// }
	}
}
